package com.miao.view
{
	import com.greensock.events.LoaderEvent;
	import com.greensock.loading.DataLoader;
	import com.greensock.loading.LoaderMax;
	import com.greensock.loading.data.*;
	import com.miao.model.ConfigProxy;
	import com.miao.model.vo.ProgressVo;
	import com.miao.utils.Consts;
	import com.miao.utils.IListUtil;
	import com.miao.view.events.ObjectEvent;
	
	import flash.events.Event;
	import flash.filesystem.File;
	import flash.filesystem.FileMode;
	import flash.filesystem.FileStream;
	import flash.net.URLRequest;
	import flash.net.URLRequestHeader;
	import flash.utils.ByteArray;
	
	import mx.collections.ArrayCollection;
	
	import org.puremvc.as3.multicore.patterns.mediator.Mediator;
	
	public class DownLoadManagerMediator extends Mediator
	{
		
		public static const NAME:String = "DownLoadManagerMediator";
		
		private var _quene:LoaderMax;
		private var _manager:DownLoadManager;
		private var _loadingList:ArrayCollection = new ArrayCollection();
		
		public function DownLoadManagerMediator(viewComponent:Object=null)
		{
			super(NAME, viewComponent);
			
			var vars:LoaderMaxVars = new LoaderMaxVars();
			vars.name("DownLoadManagerMediator_quene")
				.maxConnections(2)
				.auditSize(false)
				.onChildComplete(onChildComplete)
				.onChildFail(onChildFail)
				.onChildCancel(onChildCancel)
				.onChildProgress(onChildProgress)
				.onComplete(onComplete);
			
			_quene = new LoaderMax(vars);
		}
		
		public function openWindow():void{
			if(!_manager||_manager.closed){
				_manager = new DownLoadManager();
				_manager.open(false);
				_manager.dataProvider = _loadingList;
				_manager.dg.addEventListener("resume", managerEvt);
				_manager.dg.addEventListener("pause", managerEvt);
				_manager.dg.addEventListener("cancel", managerEvt);
				_manager.addEventListener(Event.CLOSING, handleClosingEvt);
			}
			
			_manager.activate();
		}
		
		public function closeWindow():void{
			if(_manager&&!_manager.closed){
				_manager.close();
			}
		}
		
		private function handleClosingEvt(e:Event):void{
			_manager.dg.removeEventListener("resume", managerEvt);
			_manager.dg.removeEventListener("pause", managerEvt);
			_manager.dg.removeEventListener("cancel", managerEvt);
			_manager.removeEventListener(Event.CLOSING, handleClosingEvt);
		}
		
		public function isLoaded(url:String):Boolean{
			var file:File = new File(getLocalPath(url));
			return file.exists;
		}
		
		public function getLocalPath(url:String):String{
			if(url.search(/(http:\/\/|https:\/\/)/)==0){
				return File.applicationDirectory.nativePath+"/assets/data/swf/"+url.replace(/^(http:\/\/|https:\/\/)/,"");
			}else{
				return url;
			}
		}
		
		public function append(url:String):void{
			var index:int = IListUtil.getIndexInIList(_loadingList, "label", url);
			if(index!=-1) return;
			
			var config:ConfigProxy = facade.retrieveProxy(ConfigProxy.NAME) as ConfigProxy;
			
			var urlR:URLRequest = new URLRequest();
			urlR.url = url;
			var refererUrl:String = config.getRefererUrl(url);
			if(url!=null){
				urlR.requestHeaders = [new URLRequestHeader("Referer", refererUrl)];
			}
			
			_quene.append(new DataLoader(urlR, new DataLoaderVars({rawUrl:url}).name(url).format('binary')));
			_loadingList.addItem({label:url, percent:0});
		}
		
		public function load():void{
			_quene.load();
		}
		
		public function cancel():void{
			_quene.cancel();
		}
		
		public function clear():void{
			_quene.empty();
			_loadingList.removeAll();
		}
		
		private function onChildComplete(e:LoaderEvent):void{
			var loader:DataLoader = e.target as DataLoader;
			
			var rawUrl:String = loader.vars.rawUrl;
			var bytes:ByteArray = loader.content as ByteArray;
			
			var file:File = new File(File.applicationDirectory.nativePath+"/assets/data/swf/"+rawUrl.replace(/^(http:\/\/|https:\/\/)/,""));
			file.parent.createDirectory();
			var fs:FileStream = new FileStream();
			fs.open(file, FileMode.WRITE);
			fs.writeBytes(bytes, 0, loader.bytesTotal);
			fs.close();
			/*var file2:File = new File(File.applicationDirectory.nativePath+"/../.project");
			if(file2.exists){
				file2 = new File(File.applicationDirectory.nativePath+"/../src/assets/data/swf/"+rawUrl.replace(/^(http:\/\/|https:\/\/)/,""));
				file2.parent.createDirectory();
				file.copyTo(file2, true);
			}*/
			
			var index:int = IListUtil.getIndexInIList(_loadingList, "label", rawUrl);
			if(index!=-1) _loadingList.removeItemAt(index);
			
			sendNotification(Consts.SOURCE_COMPLETE, loader.vars.rawUrl);
		}
		
		private function onChildFail(e:LoaderEvent):void{
			var loader:DataLoader = e.target as DataLoader;
			
			sendNotification(Consts.SOURCE_FAIL, loader.vars.rawUrl);
		}
		
		private function onChildCancel(e:LoaderEvent):void{
			var loader:DataLoader = e.target as DataLoader;
			
			sendNotification(Consts.SOURCE_CANCEL, loader.vars.rawUrl);
		}
		
		private function onChildProgress(e:LoaderEvent):void{
			var loader:DataLoader = e.target as DataLoader;
			
			var vo:ProgressVo = new ProgressVo();
			vo.bytesLoaded = loader.bytesLoaded;
			vo.bytesTotal = loader.bytesTotal;
			vo.rawUrl = loader.vars.rawUrl;
			
			var index:int = IListUtil.getIndexInIList(_loadingList, "label", loader.vars.rawUrl);
			if(index!=-1){
				var obj:Object = _loadingList.getItemAt(index);
				obj.percent = vo.bytesLoaded/vo.bytesTotal;
				_loadingList.setItemAt(obj, index);
			}
			
			sendNotification(Consts.SOURCE_PROGRESS, vo);
		}
		
		private function managerEvt(e:ObjectEvent):void{
			var dl:DataLoader = _quene.getLoader(e.carryObj.label) as DataLoader;
			if(!dl) return;

			if(e.type=="pause"){
				dl.pause();
			}else if(e.type=="resume"){
				dl.resume();
			}else if(e.type=="cancel"){
				dl.cancel();
				dl.unload();
				_quene.remove(dl);
				var index:int = IListUtil.getIndexInIList(_loadingList, "label", e.carryObj.label);
				if(index!=-1) _loadingList.removeItemAt(index);
			}
		}
		
		private function onComplete(e:LoaderEvent):void{
			trace("所有数据加载完成！");
		}
		
	}
}